package org.xx.armory.db.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xx.armory.commons.ForLogging;
import org.xx.armory.db.Transaction;
import org.xx.armory.db.TransactionProperties;

import javax.sql.DataSource;
import java.util.Set;

/**
 * 独占式的事务，同一时间只能有一个使用者。
 * <p>使用者被登记时启动事务，使用者被撤销时关闭事务。如果该事务已有使用者，再登记新的使用者会抛出{@link IllegalStateException}异常。</p>
 */
public class MonopolyTransaction
        extends AbstractTransaction
        implements Transaction {
    @ForLogging
    private final Logger logger = LoggerFactory.getLogger(MonopolyTransaction.class);

    /**
     * 构造{@code MonopolyTransaction}实例。
     *
     * @param dataSource
     *         事务使用的数据源。
     * @param properties
     *         事务的属性。
     */
    public MonopolyTransaction(
            DataSource dataSource,
            TransactionProperties properties
    ) {
        super(dataSource, properties);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected boolean doEnroll(
            Set<Object> users,
            Object user
    ) {
        if (users.size() > 0) {
            throw new IllegalStateException("user " + users.iterator().next() + " already exists");
        }

        return super.doEnroll(users, user);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected boolean doRevoke(
            Set<Object> users,
            Object user
    ) {
        if (users.contains(user)) {
            users.clear();

            return true;
        } else {
            return false;
        }
    }
}
